<script setup lang="tsx">
import { usePagination } from '@sa/alova/client';
import { NButton, NPopconfirm, NTag } from 'naive-ui';
import type { HTMLAttributes } from 'vue';
import { reactive } from 'vue';
import useCheckedColumns from '@/hooks/common/table/table-columns';
import useTableOperate from '@/hooks/common/table/table-operate';
import { $t } from '@/locales';
import {
  batchDeleteDict,
  batchDeleteDictItem,
  deleteDict,
  deleteDictItem,
  paginateDict,
  paginateDictItem
} from '@/service/api/manage';
import { useAppStore } from '@/store/modules/app';
import PorDictTag from '@/components/_builtin/por-dict-tag/index.vue';
import DictItemOperateDrawer from './modules/dict-item-operate-drawer.vue';
import DictItemSearch from './modules/dict-item-search.vue';
import DictOperateDrawer from './modules/dict-operate-drawer.vue';
import DictSearch from './modules/dict-search.vue';

const appStore = useAppStore();

// 字典表
const dictSearchParams = reactive({
  status: null,
  keyword: null
});

const {
  loading: dictLoading,
  data: dictData,
  refresh: dictRefresh,
  page: dictPage,
  pageSize: dictPageSize,
  pageCount: dictPageCount,
  send: dictSend,
  remove: dictRemove
} = usePagination(
  (pageNum, size) =>
    paginateDict({
      ...dictSearchParams,
      pageNumber: pageNum,
      pageSize: size
    }),
  {
    data: ({ records }) => records,
    total: ({ total }) => total,

    // trigger reload when states in `searchParams` changed
    watchingStates: [dictSearchParams],

    // debounce of `searchParams`
    debounce: [500]
  }
);

const getDictDataByPage = (newPage = 1) => {
  dictPage.value = newPage;
  dictSend(dictPage.value, dictPageSize.value);
};

const {
  drawerVisible: dictDrawerVisible,
  operateType: dictOperateType,
  editingData: dictEditingData,
  handleAdd: handleDictAdd,
  handleEdit: handleDictEdit,
  checkedRowKeys: checkedDictRowKeys,
  handleBatchDelete: handleDictBatchDelete,
  handleDelete: handleDictDelete
} = useTableOperate(dictData, {
  async delete(row) {
    await deleteDict(row.id as number);
    dictRemove(row);
  },
  async batchDelete(rows) {
    await batchDeleteDict(rows.map(({ id }) => id as number));
    dictRemove(...rows);
  }
});

const { columnChecks: dictColumnChecks, columns: dictColumns } = useCheckedColumns<typeof paginateDict>(() => [
  {
    type: 'selection',
    align: 'center',
    width: 48
  },
  {
    key: 'name',
    title: '名称',
    align: 'center',
    minWidth: 100
  },
  {
    key: 'code',
    title: '编码',
    align: 'center',
    minWidth: 100
  },
  {
    key: 'status',
    title: '状态',
    align: 'center',
    width: 100,
    render: row => {
      if (row.status === null) {
        return <NTag></NTag>;
      }
      return <PorDictTag dict-code="common_status" value={row.status}></PorDictTag>;
    }
  },
  {
    key: 'operate',
    title: '操作',
    align: 'center',
    width: 130,
    fixed: 'right',
    render: row => (
      <div class="flex-center gap-8px">
        <NButton type="primary" ghost size="small" onClick={() => editDict(row.id as number)}>
          {$t('common.edit')}
        </NButton>
        <NPopconfirm onPositiveClick={() => handleDictDelete(row.id as number)}>
          {{
            default: () => $t('common.confirmDelete'),
            trigger: () => (
              <NButton type="error" ghost size="small">
                {$t('common.delete')}
              </NButton>
            )
          }}
        </NPopconfirm>
      </div>
    )
  }
]);

// 字典项表格
const dictItemSearchParams = reactive({
  status: null,
  keyword: '',
  dictCode: '',
  dictName: ''
});
const {
  loading: dictItemLoading,
  data: dictItemData,
  refresh: dictItemRefresh,
  page: dictItemPage,
  pageSize: dictItemPageSize,
  pageCount: dictItemPageCount,
  send: dictItemSend,
  remove: dictItemRemove
} = usePagination(
  (pageNum, size) =>
    paginateDictItem({
      ...dictItemSearchParams,
      pageNumber: pageNum,
      pageSize: size
    }),
  {
    data: ({ records }) => records,
    total: ({ total }) => total,

    // trigger reload when states in `searchParams` changed
    watchingStates: [dictItemSearchParams],

    // debounce of `searchParams`
    debounce: [500]
  }
);
const getDictItemDataByPage = (newPage = 1) => {
  dictItemPage.value = newPage;
  dictItemSend(dictItemPage.value, dictItemPageSize.value);
};

const {
  drawerVisible: dictItemDrawerVisible,
  operateType: dictItemOperateType,
  editingData: dictItemEditingData,
  handleAdd: handleDictItemAdd,
  handleEdit: handleDictItemEdit,
  checkedRowKeys: checkedDictItemRowKeys,
  handleDelete: handleDictItemDelete,
  handleBatchDelete: handleDictItemBatchDelete
  // closeDrawer
} = useTableOperate(dictItemData, {
  async delete(row) {
    await deleteDictItem(row.id as number);
    dictItemRemove(row);
  },
  async batchDelete(rows) {
    await batchDeleteDictItem(rows.map(({ id }) => id as number));
    dictItemRemove(...rows);
  }
});

const { columnChecks: dictItemColumnChecks, columns: dictItemColumns } = useCheckedColumns<typeof paginateDictItem>(
  () => [
    {
      type: 'selection',
      align: 'center',
      width: 48
    },
    {
      key: 'name',
      title: '名称',
      align: 'center',
      minWidth: 100
    },
    {
      key: 'value',
      title: '值',
      align: 'center',
      minWidth: 100
    },
    {
      key: 'status',
      title: '状态',
      align: 'center',
      width: 100,
      render: row => {
        if (row.status === null) {
          return <NTag></NTag>;
        }

        return <PorDictTag dict-code="common_status" value={row.status}></PorDictTag>;
      }
    },
    {
      key: 'remark',
      title: '备注',
      align: 'center',
      hidden: 120
    },
    {
      key: 'operate',
      title: '操作',
      align: 'center',
      width: 130,
      fixed: 'right',
      render: row => (
        <div class="flex-center gap-8px">
          <NButton type="primary" ghost size="small" onClick={() => editDictItem(row.id as number)}>
            {$t('common.edit')}
          </NButton>
          <NPopconfirm onPositiveClick={() => handleDictItemDelete(row.id as number)}>
            {{
              default: () => $t('common.confirmDelete'),
              trigger: () => (
                <NButton type="error" ghost size="small">
                  {$t('common.delete')}
                </NButton>
              )
            }}
          </NPopconfirm>
        </div>
      )
    }
  ]
);

function editDictItem(id: number) {
  handleDictItemEdit(id);
}

// 字典表格操作
function handleDictRowProps(row: Api.Manage.Dict): HTMLAttributes {
  return {
    onClick: () => {
      dictItemSearchParams.dictCode = row.code;
      dictItemSearchParams.dictName = row.name;
      getDictItemDataByPage();
    }
  };
}

function editDict(id: number) {
  handleDictEdit(id);
}
</script>

<template>
  <NSplit :size="0.4" pane1-class="pr-2" pane2-class="pl-2" :resize-trigger-size="0">
    <template #1>
      <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
        <DictSearch v-model:model="dictSearchParams" @search="getDictDataByPage" />
        <NCard title="字典列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
          <template #header-extra>
            <TableHeaderOperation
              v-model:columns="dictColumnChecks"
              :disabled-delete="checkedDictRowKeys.length === 0"
              :hide-delete="true"
              :loading="dictLoading"
              @add="handleDictAdd"
              @delete="handleDictBatchDelete"
              @refresh="dictRefresh"
            />
          </template>
          <NDataTable
            v-model:checked-row-keys="checkedDictRowKeys"
            :columns="dictColumns"
            :data="dictData"
            size="small"
            :loading="dictLoading"
            remote
            :row-key="row => row.id"
            :pagination="{
              page: dictPage,
              pageSize: dictPageSize,
              showSizePicker: true,
              pageCount: dictPageCount,
              pageSizes: [10, 15, 20, 25, 30],
              onUpdatePage(value) {
                dictPage = value;
              },
              onUpdatePageSize(value) {
                dictPageSize = value;
              }
            }"
            :scroll-x="600"
            class="sm:h-full"
            min-height="350px"
            :flex-height="!appStore.isMobile"
            :row-props="handleDictRowProps"
          />
        </NCard>
        <DictOperateDrawer
          v-model:visible="dictDrawerVisible"
          :operate-type="dictOperateType"
          :row-data="dictEditingData"
          @submitted="dictRefresh"
        />
      </div>
    </template>
    <template #2>
      <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
        <DictItemSearch v-model:model="dictItemSearchParams" @search="getDictItemDataByPage" />
        <NCard title="字典项列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
          <template #header-extra>
            <TableHeaderOperation
              v-model:columns="dictItemColumnChecks"
              :disabled-delete="checkedDictItemRowKeys.length === 0"
              :loading="dictItemLoading"
              @add="handleDictItemAdd"
              @delete="handleDictItemBatchDelete"
              @refresh="dictItemRefresh"
            />
          </template>
          <NDataTable
            v-model:checked-row-keys="checkedDictItemRowKeys"
            :columns="dictItemColumns"
            :data="dictItemData"
            size="small"
            :scroll-x="600"
            :loading="dictItemLoading"
            remote
            :row-key="row => row.id"
            :pagination="{
              page: dictItemPage,
              pageSize: dictItemPageSize,
              showSizePicker: true,
              pageCount: dictItemPageCount,
              pageSizes: [10, 15, 20, 25, 30],
              onUpdatePage(value) {
                dictItemPage = value;
              },
              onUpdatePageSize(value) {
                dictItemPageSize = value;
              }
            }"
            class="sm:h-full"
            min-height="350px"
            :flex-height="!appStore.isMobile"
          />
          <DictItemOperateDrawer
            v-model:visible="dictItemDrawerVisible"
            :operate-type="dictItemOperateType"
            :row-data="dictItemEditingData"
            :dict-code="dictItemSearchParams.dictCode"
            @submitted="dictItemRefresh"
          />
        </NCard>
      </div>
    </template>
  </NSplit>
</template>

<style scoped></style>
